package map.tools.interactions;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.util.EList;

import uimigration.Interactions.Behaviour;
import uimigration.Interactions.EditContent;
import uimigration.Interactions.SelectContent;
import uimigration.WidgetsModel.APIModel;
import uimigration.mappingmodel.MappingBehaviourEvent;
import uimigration.mappingmodel.MappingTable;
import uimigration.mappingmodel.WidgetEvent;
import uimigration.mappingmodel.impl.MappingTableImpl;

public class WidgetBehaviorTable implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private APIModel apimodel;
	private String fileName;
	private List<EventBehaviour> table=null;
	public WidgetBehaviorTable(){
		
		if(table==null)
			table= new ArrayList<EventBehaviour>();		
	}
	
	public WidgetBehaviorTable(MappingTable mapping){
		if(table==null)
			table= new ArrayList<EventBehaviour>();
		for(MappingBehaviourEvent beh:mapping.getBehaviorsMapping()){
			for(WidgetEvent we:beh.getMappedEvent()){
					EList<Behaviour> lb=we.getMappedBehavoiurs();
					for(Behaviour b:lb)
						if(b!=null){
							EventBehaviour eb= new EventBehaviour(we.getName(), b, b.getType().toString());
							table.add(eb);
						}
			}
		}
	}
	public String getEquivalentEvent(List<Behaviour> eList)
	{
		for(EventBehaviour e : table)
		{
			if(e.behavior !=null)
			{
				if(equivalentBehaviours(e.behavior, eList))
					return e.event;
			}
		}
		return "";
	}
	private boolean equivalentBehaviours(List<Behaviour> l1, List<Behaviour> l2)
	{
		int s1= l1.size();
		for(Behaviour b1 : l1)
		{
			for(Behaviour b2: l2)
			{
				if(equalBehaviour(b1, b2))
				{
					s1--;
				}
			}
		}
		if(s1==0)
			return true;
		return false;
	}
	private boolean equalBehaviour(Behaviour b1, Behaviour b2)
	{
		if(b1.eClass().getName().compareTo(b2.eClass().getName())==0)
		{
			try {
				if(((EditContent)b1).getEditatbleContent()!=null && ((EditContent)b2).getEditatbleContent()!=null)
				{
					int n =((EditContent)b1).getEditatbleContent().size();
					if(((EditContent)b1).getEditatbleContent().size()== ((EditContent)b2).getEditatbleContent().size()){
						for(int i=0;i<((EditContent)b1).getEditatbleContent().size();i++)
						{
							if(((EditContent)b1).getEditatbleContent().get(i)==(((EditContent)b1).getEditatbleContent().get(i)))
								n--;
						}
						
					}
					if( n==0)
						return true;
					else 
						return false;
				}
				else
					return true;
				
			} catch (ClassCastException e) {
				try {
					if(((SelectContent)b1).getSelectableContentList()!=null && ((SelectContent)b2).getSelectableContentList()!=null)
					{
						int n =((SelectContent)b1).getSelectableContentList().size();
						if(((SelectContent)b1).getSelectableContentList().size()== ((SelectContent)b2).getSelectableContentList().size()){
							for(int i=0;i<((SelectContent)b1).getSelectableContentList().size();i++)
							{
								if(((SelectContent)b1).getSelectableContentList().get(i)==(((SelectContent)b1).getSelectableContentList().get(i)))
									n--;
							}
							
						}
						if( n==0)
							return true;
						else 
							return false;
						
					}
					else
						return true;
				} catch (ClassCastException e2) {
				
				}
			}
			return true;
		}
		return false;
	}
	public void addElement(String event, EList<Behaviour> eList,String type){
		//System.out.println("Type"+type);
		EventBehaviour eb= new EventBehaviour(event, eList, type);
		table.add(eb);
	}
	public List<Behaviour> getBehaviors(String event){
		List<Behaviour> behaviors= null;
		for(EventBehaviour eb : table){
			if(eb.event.compareTo(event)==0){
				if(  behaviors==null)
					behaviors= new ArrayList<Behaviour>();
				for(Behaviour b:eb.behavior)
					behaviors.add(b);
			}
		}
		return behaviors;
	}
	public boolean removeElement (String eventName){
		//TODO:
		return true;
	}
	public void addBehavior(String event, Behaviour b){
		EventBehaviour e=foundEvent(event);
		if(e!=null)
			e.addBehavior(b);
	}
	public boolean isProperty(String name){
		if(!isEvent(name) )
			return true;
		return false;
	}
	private EventBehaviour foundEvent(String event){
		for(EventBehaviour eb:table){
			if(eb.event.compareTo(event)==0)
			{
				return eb;
			}
		}
		return null;
	}


	public void setTable(MappingTableImpl mapping){
		if(table==null)
			table= new ArrayList<EventBehaviour>();		
		if(mapping !=null)
			for(MappingBehaviourEvent beh:mapping.getBehaviorsMapping()){
				for(WidgetEvent ev:(beh.getMappedEvent()))
					for(Behaviour b:ev.getMappedBehavoiurs())
						addElement(ev.getName(),  ev.getMappedBehavoiurs(),b.getType().toString());
			}
	}
	
	
	public boolean isEvent(String name){
		if(foundEvent(name)!=null)
			return true;
		else return false;
	}
	public boolean isLinkedProperty(String name){
		for(EventBehaviour eb:table)
			for(String lp:eb.linkedProperties)
				if(name.equals(lp))
					return true;
		return false;
	}
	public List<String> getLinkedPropertie(String name){
		EventBehaviour eb= foundEvent(name);
		if(eb!=null)
		{
			return eb.linkedProperties();
		}
		return null;
	}

	public void setApimodel(APIModel apimodel) {
		this.apimodel = apimodel;
	}

	public APIModel getApimodel() {
		return apimodel;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getFileName() {
		return fileName;
	}
	public Object[][]getData(){
		Object [][] data;
		data=new Object[table.size()][4];
		int i=0;
		for(EventBehaviour eb:table){
			data[i][0]= eb.event;
			int j=0;
			if(eb.type.contains("Render"))
				j=1;
			else if(eb.type.contains("Content"))
				j=2;
			else if(eb.type.contains("Link"))
				j=3;
			String be="";
			if(eb.behavior!=null)
				for(Behaviour b : eb.behavior)
					be+=(" "+b.getClass().getInterfaces()[0].getSimpleName());
			data[i][j]=be;
			i++;
		}
		return data;
		
	}
}
class EventBehaviour{
	public String event=null;
	public ArrayList<Behaviour> behavior=null;
	public String type="Link"; //Rendu, Contenu, Lien
	public List<String> linkedProperties;
	public EventBehaviour(String ev,EList<Behaviour> eList, String t){
		event=ev;
		if(behavior==null)
			behavior= new ArrayList<Behaviour>();
		if(eList!=null)
		{	for(Behaviour b:eList)
				if(!contains(b))
					behavior.add(b);
		}
		if(t!=null)
			type=t;
	}
	public EventBehaviour(String ev,Behaviour lb, String t){
		event=ev;
		if(behavior==null)
			behavior= new ArrayList<Behaviour>();
		if(lb!=null)
		{	if(!contains(lb))
				behavior.add(lb);
		}
		if(t!=null)
			type=t;
	}

	public List<String> linkedProperties() {
		// TODO Auto-generated method stub
		return null;
	}
	
	public void addBehavior(Behaviour b){
		if(!contains(b))
			behavior.add(b);
	}
	private boolean contains(Behaviour b) {
		for(Behaviour bi: behavior){
			if(b.eClass().getName().equals(bi.eClass().getName()))
					if(b.getIdBehavior()==bi.getIdBehavior())
						return true;
						
		}
		return false;
	}
}
